import cn.hutool.core.collection.CollectionUtil;
import lombok.Data;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 目标内容对象
 * @author near
 */
@Data
public class TargetNewContent extends RandomIO implements IRandomObj  {


    @Override
    public String getKeyWord() {
        return this.target;
    }

    @Override
    public void writeToFile(OptimizedRandomAccessFile out) throws IOException {
        writeString(newContent,out);
    }

    @Override
    public boolean replaceBulk(OptimizedRandomAccessFile oraf,boolean needClose) throws Exception {
        Map<String, Long> posMap = searchPos(this, oraf);
        if(CollectionUtil.isNotEmpty(posMap)){
            long newContentEndPos = -1;
            Long startPos = posMap.get(Constants.START_POS);
            Long endPos = posMap.get(Constants.END_POS);
            Long replaceEndPos = posMap.get(Constants.REPLACE_END_POS);
            String currentLine;
            StringBuilder holdContent = getHoldContent(oraf,replaceEndPos);

            //将匹配到的内容写入进文件中去
            String matchContent = this.getNewContent();
            //替换内容中包含\r\n
            String[] split = matchContent.split("\\\\r\\\\n");
            int iterateCount = split.length;
            StringBuilder replaceContent = new StringBuilder();
            for (String s : split) {
                replaceContent.append(s).append(Constants.LINE_FEED);
            }
            oraf.seek(endPos);
            oraf.write(replaceContent.toString().getBytes(StandardCharsets.UTF_8));
            oraf.seek(endPos);
            int count = 0;
            while((currentLine = oraf.readLine()) != null){
                count++;
                if( iterateCount == count ){
                    //新内容结束坐标
                    newContentEndPos = oraf.getFilePointer();
                    break;
                }
            }
            long delLength = replaceEndPos - endPos;
            long newDelLength = newContentEndPos - endPos;
            long needDel = delLength - newDelLength;
            oraf.write(holdContent.toString().getBytes(StandardCharsets.UTF_8));
            if( needDel > 0 ){
                long length = oraf.length();
                oraf.setLength(length-needDel);
            }
        }
        if( needClose ) {
            oraf.close();
        }
        return true;
    }

    @Override
    public boolean replaceOneLine(OptimizedRandomAccessFile oraf, boolean needClose) throws Exception {
        Map<String, Long> posMap = searchPos(this, oraf);
        if (CollectionUtil.isNotEmpty(posMap)){
            Long startPos = posMap.get(Constants.START_POS);
            Long endPos = posMap.get(Constants.END_POS);
            long delLength = endPos - startPos;
            StringBuilder holdContent = getHoldContent(oraf, endPos);
            oraf.seek(startPos);
            //新权限行内容-单行
            String oneLineNewContent = this.getNewContent();
            StringBuilder replaceContent = new StringBuilder();
            replaceContent.append(oneLineNewContent).append(Constants.LINE_FEED);
            writeString(replaceContent.toString(),oraf);
            oraf.seek(startPos);
            oraf.readLine();
            long newEndPos = oraf.getFilePointer();
            long newDelLength = newEndPos - startPos;
            long needDel = delLength - newDelLength;
            oraf.write(holdContent.toString().getBytes(StandardCharsets.UTF_8));
            if( needDel > 0 ){
                long length = oraf.length();
                oraf.setLength(length-needDel);
            }
        }
        if( needClose ) {
            oraf.close();
        }
        return true;
    }


    @Override
    public boolean insertBulk(OptimizedRandomAccessFile oraf, boolean needClose) throws Exception {
        Map<String, Long> posMap = searchPos(this, oraf);
        if (CollectionUtil.isNotEmpty(posMap)){
            Long startPos = posMap.get(Constants.START_POS);
            Long endPos = posMap.get(Constants.END_POS);

            StringBuilder holdContent = getHoldContent(oraf, endPos);

            //将匹配到的内容写入进文件中去
            String insertContent = this.getNewContent();
            //替换内容中包含\r\n
            String[] split = insertContent.split("\\\\r\\\\n");
            int iterateCount = split.length;
            StringBuilder insertContentBuild = new StringBuilder();
            for (String s : split) {
                insertContentBuild.append(s).append(Constants.LINE_FEED);
            }
            oraf.seek(endPos);
            oraf.write(insertContentBuild.toString().getBytes(StandardCharsets.UTF_8));

            oraf.write(holdContent.toString().getBytes(StandardCharsets.UTF_8));

        }
        if( needClose ) {
            oraf.close();
        }
        return true;
    }


}
